package groovy.jmx.builder.modelmbean

import groovy.jmx.builder.node.MBeanNodeData
import groovy.jmx.builder.node.OpNodeData
import java.lang.reflect.Constructor
import javax.management.Descriptor
import javax.management.MBeanParameterInfo
import javax.management.modelmbean.DescriptorSupport
import javax.management.modelmbean.ModelMBeanConstructorInfo




class ModelMBeanConstructorCollector {
    public List<ModelMBeanConstructorInfo> collectConstructorInfo(MBeanNodeData data) {
        List<ModelMBeanConstructorInfo> result = []
        List<Constructor> ctors = data?.object.getClass().constructors

        if (ctors) {
            ctors.each {ctor ->
                ModelMBeanConstructorInfo info
                OpNodeData ctorNode = CollectorHelper.getOpNodeData(data, ctor)
                if (ctorNode) {
                    info = getMBeanConstructorInfo(ctor, ctorNode)
                    result.add(info)
                }
            }
        }
        return result
    }

    public List<ModelMBeanConstructorInfo> collectConstructorInfo(def instance) {
        List<ModelMBeanConstructorInfo> result = []
        List<Constructor> ctors = instance?.getClass().constructors

        if (ctors) {
            ctors.each {ctor ->
                ModelMBeanConstructorInfo info
                info = getMBeanConstructorInfo(ctor)
                result.add(info)
            }
        }
        return result
    }

    private ModelMBeanConstructorInfo getMBeanConstructorInfo(Constructor ctor, OpNodeData data) {
        ModelMBeanConstructorInfo ctorInfo;
        if (data && ctor) {
            Descriptor desc = new DescriptorSupport()
            desc.setField("name", ctor.name)
            desc.setField("descriptorType", "operation")
            desc.setField("role", "constructor")
            desc.setField("displayName", data.description)

            // add any addtional fields
            data?.value.each {key, value ->
                desc.setField(key, value)
            }

            MBeanParameterInfo[] params = CollectorHelper.collectParamInfo(data)?.toArray()
            ctorInfo = new ModelMBeanConstructorInfo(
                    ctor.name,
                    data.description,
                    params,
                    desc
            );

        }
        return ctorInfo
    }

    private ModelMBeanConstructorInfo getMBeanConstructorInfo(Constructor ctor) {
        ModelMBeanConstructorInfo ctorInfo;
        if (ctor) {
            Descriptor desc = new DescriptorSupport()
            desc.setField("name", ctor.name)
            desc.setField("descriptorType", "operation")
            desc.setField("role", "constructor")
            desc.setField("displayName", "Constructor")

            MBeanParameterInfo[] params = CollectorHelper.collectParamInfo(ctor)?.toArray()
            ctorInfo = new ModelMBeanConstructorInfo(
                    ctor.name,
                    "Constructor ${ctor.name}",
                    params,
                    desc
            );

        }
        return ctorInfo
    }

}